package com.mindata.blockchain.socket.distruptor;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.mindata.blockchain.socket.base.AbstractBlockHandler;
import com.mindata.blockchain.socket.distruptor.base.BaseEvent;
import com.mindata.blockchain.socket.distruptor.base.MessageConsumer;
import com.mindata.blockchain.socket.handler.server.FetchBlockRequestHandler;
import com.mindata.blockchain.socket.handler.server.GenerateBlockRequestHandler;
import com.mindata.blockchain.socket.handler.server.GenerateCompleteRequestHandler;
import com.mindata.blockchain.socket.handler.server.HeartBeatHandler;
import com.mindata.blockchain.socket.handler.server.NextBlockRequestHandler;
import com.mindata.blockchain.socket.handler.server.PbftVoteHandler;
import com.mindata.blockchain.socket.handler.server.TotalBlockInfoRequestHandler;
import com.mindata.blockchain.socket.packet.BlockPacket;
import com.mindata.blockchain.socket.packet.PacketType;

/**
 * 所有client发来的消息都在这里处理
 * @author wuweifeng wrote on 2018/4/20.
 */
@Component
public class DisruptorServerConsumer implements MessageConsumer {

	private static final Logger logger=LoggerFactory.getLogger(DisruptorServerConsumer.class);
    private static Map<Byte, AbstractBlockHandler<?>> handlerMap = new HashMap<>();

    static {
        handlerMap.put(PacketType.GENERATE_COMPLETE_REQUEST, new GenerateCompleteRequestHandler());
        handlerMap.put(PacketType.GENERATE_BLOCK_REQUEST, new GenerateBlockRequestHandler());
        handlerMap.put(PacketType.TOTAL_BLOCK_INFO_REQUEST, new TotalBlockInfoRequestHandler());
        handlerMap.put(PacketType.FETCH_BLOCK_INFO_REQUEST, new FetchBlockRequestHandler());
        handlerMap.put(PacketType.HEART_BEAT, new HeartBeatHandler());
        handlerMap.put(PacketType.NEXT_BLOCK_INFO_REQUEST, new NextBlockRequestHandler());
        handlerMap.put(PacketType.PBFT_VOTE, new PbftVoteHandler());
    }

    @Override
    public void receive(BaseEvent baseEvent) throws Exception {
    	logger.info("disruptor receive data");
        BlockPacket blockPacket = baseEvent.getBlockPacket();
        Byte type = blockPacket.getType();
        AbstractBlockHandler<?> handler = handlerMap.get(type);
        if (handler == null) {
            return;
        }
        logger.info("server blockhandler->{},data->",handler.getClass(),blockPacket);
        handler.handler(blockPacket, baseEvent.getChannelContext());
    }
}
